package nl.rainbowsheep.reisorg.rest.service.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.MapKeyJoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.PostLoad;
import javax.persistence.PostUpdate;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.validation.constraints.NotNull;
import nl.rainbowsheep.reisorg.rest.service.util.Localizer;
import org.springframework.format.annotation.DateTimeFormat;

@Entity
@Table(name = "trips")
public class Trip implements Serializable, ILocalized {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "trip_id")
    private long id;

    @OneToMany(mappedBy="accommodationTrip", cascade=CascadeType.ALL, fetch = FetchType.EAGER)
    private List<TripAccommodation> tripAccommodations;

    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "trips_locale", joinColumns = @JoinColumn(name = "trips_fk"))
    @MapKeyJoinColumn(name = "languages_fk")
    private Map<Language, TripLocalized> locale;

    @Column(name = "customer_fk")
    private Long customerId;

    @Column(name = "travelgroup_fk")
    private Long travelGroupId;

    @Column(name = "start_date")
    @NotNull
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date startDate;

    @Column(name = "end_date")
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date endDate;

    @Column(name = "fake_title")
    private String title;

    @Column(name = "fake_description")
    private String description;

    @Column(name = "last_update")
    @NotNull
    @DateTimeFormat(pattern = "dd-MM-yyyy HH:mm:SS")
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date lastUpdate;

    @Column(name = "status")
    @NotNull
    private int status;

    @Column(name = "min_persons")
    @NotNull
    private int minPersons;

    @Column(name = "max_persons")
    @NotNull
    private int maxPersons;

    @Column(name = "is_predefined")
    @NotNull
    private boolean isPredefined;

    @Column(name = "amount_nights")
    @NotNull
    private int amount_nights;

    @Column(name = "price")
    @NotNull
    private BigDecimal price;
    
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public Long getCustomerId() {
        return customerId;
    }

    public void setCustomerId(Long customerId) {
        this.customerId = customerId;
    }

    public Long getTravelGroupId() {
        return travelGroupId;
    }

    public void setTravelGroupId(Long travelGroupId) {
        this.travelGroupId = travelGroupId;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public Date getLastUpdate() {
        return lastUpdate;
    }

    public void setLastUpdate(Date lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public int getMinPersons() {
        return minPersons;
    }

    public void setMinPersons(int minPersons) {
        this.minPersons = minPersons;
    }

    public int getMaxPersons() {
        return maxPersons;
    }

    public void setMaxPersons(int maxPersons) {
        this.maxPersons = maxPersons;
    }

    public boolean isIsPredefined() {
        return isPredefined;
    }

    public void setIsPredefined(boolean isPredefined) {
        this.isPredefined = isPredefined;
    }

    public int getAmount_nights() {
        return amount_nights;
    }

    public void setAmount_nights(int amount_nights) {
        this.amount_nights = amount_nights;
    }

    public List<TripAccommodation> getTripAccommodations() {
        return tripAccommodations;
    }

    public void setTripAccommodations(List<TripAccommodation> tripAccommodations) {
        this.tripAccommodations = tripAccommodations;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    @JsonIgnore
    @Override
    public Map getLocale() {
        return locale;
    }

    @Override
    public void setLocale(Map setLocale) {
        this.locale = setLocale;
    }

    @Override
    @PostLoad
    @PostUpdate
    public void localize() {
        TripLocalized localizedObject = (TripLocalized) Localizer.getLocalizedObject(this.locale, TripLocalized.class);
        this.description = localizedObject.getDescription();
        this.title = localizedObject.getTitle();
    }

    @Override
    @PreUpdate
    @PrePersist
    public void parseLocalizedData() {
        TripLocalized localizedObject = null;
        if (this.locale == null) {
            this.locale = new HashMap<Language, TripLocalized>();
        }
        if (Localizer.getLocalizedObject(this.locale, TripLocalized.class) != null) {
            localizedObject = (TripLocalized) Localizer.getLocalizedObject(this.locale, TripLocalized.class);
        } else {
            localizedObject = new TripLocalized();
            this.locale.put(Localizer.getCurrentLanguage(), localizedObject);
        }
        localizedObject.setDescription(this.description);
        localizedObject.setTitle(this.title);
    }
}
